import { CCFloat, CharacterController, CharacterControllerContact, Component, EventKeyboard, EventTouch, Input, KeyCode, PhysicsSystem, Vec3, _decorator, clamp, input } from "cc";
import { ecs } from "../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { EventType } from "../../common/config/EventType";

const { ccclass, property } = _decorator;

/** 视图层对象 */
@ccclass('PlayerControllerComp')
export class PlayerControllerComp extends Component {

    @property({ type: CCFloat, tooltip: '移动速度' })
    public speed: number = 0.5;
    @property({ type: CCFloat, tooltip: '重力值' })
    gravityValue: number = -9.81;
    @property({ type: CCFloat, tooltip: '跳跃速度' })
    jumpSpeed: number = 5;
    /** 表示物体在某个方向上的速度随时间逐渐减小的现象，线性阻尼的公式通常表示为 damping = -Damping * velocity，其中 Damping 是阻尼系数，velocity 是物体的速度*/
    @property({ type: CCFloat, tooltip: '阻尼系数' })
    linearDamping: number = 0.9;
    @property({ type: CCFloat, tooltip: '推力' })
    public pushPower: number = 4;


    private _cct: CharacterController = null!;
    /** 左右移动 */
    private _control_z = 0;
    /**前后移动 */
    private _control_x = 0;
    /** 移动向量 */
    private _movement = new Vec3(0, 0, 0);
    /**是否在地面 默认在 */
    private _grounded = true;
    /** 玩家速度 */
    private _playerVelocity = new Vec3(0, 0, 0);
    /** 是否允许跳跃 */
    private _doJump = true;
    /** 射线 */
    private _hitPoint: Node = null!;

    protected onLoad(): void {
        this._cct = this.node.getComponent(CharacterController)!;
        debugger
        if (this._cct) {
            this._cct.on(EventType.ControllerColliderHit, this.onControllerColliderHit, this);
            this._cct.on(EventType.ControllerTriggerEnter, this.onControllerTriggerEnter, this);
            this._cct.on(EventType.ControllerTriggerStay, this.onControllerTriggerStay, this);
            this._cct.on(EventType.ControllerTriggerExit, this.onControllerTriggerExit, this);
        }
    }
    protected onEnable(): void {
        input.on(Input.EventType.KEY_PRESSING, this.onKeyPressing, this);
        input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    }


    onControllerColliderHit(hit: CharacterControllerContact) {

    }
    onControllerTriggerEnter(event: any) { }


    onControllerTriggerStay(event: any) {
        //console.log('cct onControllerTriggerStay', event);
    }

    onControllerTriggerExit(event: any) { }


    /** 视图层逻辑代码分离演示 */
    start() {
        // var entity = this.ent as ecs.Entity;         // ecs.Entity 可转为当前模块的具体实体对象
        // this.on(ModuleEvent.Cmd, this.onHandler, this);
    }

    /** 全局消息逻辑处理 */
    // private onHandler(event: string, args: any) {
    //     switch (event) {
    //         case ModuleEvent.Cmd:
    //             break;
    //     }
    // }

    protected update(deltaTime: number): void {
        if (!this._cct)
            return;

        deltaTime = PhysicsSystem.instance.fixedTimeStep;
        this._grounded = this._cct!.isGrounded;

        // Gravity
        this._playerVelocity.y += this.gravityValue * deltaTime;

        if (this._grounded) {
            if (this._doJump) {
                this._playerVelocity.y += this.jumpSpeed;
                this._doJump = false;
            }
            else {
                //control impulse
                this._playerVelocity.z += -this._control_z * this.speed;
                this._playerVelocity.x += -this._control_x * this.speed;
                this._control_z = 0;
                this._control_x = 0;

                // damping
                this._playerVelocity.x *= this.linearDamping;
                this._playerVelocity.z *= this.linearDamping;
            }
        }

        Vec3.multiplyScalar(this._movement, this._playerVelocity, deltaTime);
        this._cct!.move(this._movement);

        if (this._grounded) {
            this._playerVelocity.y = 0;
        }
    }

    jump() {
        if (this._grounded) {
            this._doJump = true;
        }
    }

    onKeyDown(event: EventKeyboard) {
        this.keyProcess(event);
    }
    onKeyPressing(event: EventKeyboard) {
        this.keyProcess(event);
    }

    keyProcess(event: EventKeyboard) {
        const step = 1;
        switch (event.keyCode) {
            case KeyCode.KEY_W: {
                this._control_z += step;
                break;
            }
            case KeyCode.KEY_S: {
                this._control_z -= step;
                break;
            }
            case KeyCode.KEY_A: {
                this._control_x += step;
                break;
            }
            case KeyCode.KEY_D: {
                this._control_x -= step;
                break;
            }
            case KeyCode.SPACE: {
                this.jump();
                break;
            }
        }
        this._control_z = clamp(this._control_z, -1, 1);
        this._control_x = clamp(this._control_x, -1, 1);
    }

    protected onDisable(): void {
        input.off(Input.EventType.KEY_PRESSING, this.onKeyPressing, this);
        input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    }

    onTouchMove (touch: Touch, event: EventTouch) {}

    onTouchEnd (touch: Touch, event: EventTouch) {
    }

    /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
    reset() {
        this.node.destroy();
    }
}